<template>
	<zh-checkbox-group v-model="_value" :defaultValue="[]" :disabled="props.disabled" :max="props.max"
		:direction="props.direction" :align="props.align" @change="onChange">
		<zh-checkbox :followTheme="props.followTheme" v-for="(item, index) in myOptions" :key="index"
			:fontSize="props.fontSize" :border="props.border" :round="props.round" :size="props.size" :color="_color"
			:label="typeof item == 'string' ? item : item[nodeLabel]" :disabled="item.disabled"
			:value="typeof item == 'string' ? item : item[nodeValue]"></zh-checkbox>
	</zh-checkbox-group>
</template>

<script lang="ts" setup name="zh-checkbox-view">
	import { computed, PropType, ref, watch, useAttrs, defineEmits, onMounted } from 'vue';
	import http from '@/common/utils/http';
	import systemConfigStore from '@/store/modules/systemConfigStore';
	const store = systemConfigStore();
	const props = defineProps({
		followTheme: {
			type: [Boolean, String],
			default: false,
		},
		disabled: {
			type: [Boolean],
			default: false,
		},
		fieldNames: {
			type: Object,
			default: () => {
				return { label: 'dictValue', value: 'dictKey', children: 'children' };
			},
		},
		options: {
			type: Array,
			default: () => {
				return [];
			},
		},
		modelValue: {
			type: [Array],
			default: () => {
				return [];
			},
		},
		/**
		 * 注意：这里是单向输出显示的value值，而不是modelValue的index索引值。
		 * 这里主要是为了方便表单上页面的显示。如果真要保存到数据库，你应该保存modelValue的值。
		 */
		modelStr: {
			type: [Array],
			default: () => {
				return [];
			},
		},
		max: {
			type: Number,
			default: 99,
		},
		size: {
			type: Number,
			default: 42,
		},
		border: {
			type: Number,
			default: 2,
		},
		fontSize: {
			type: Number,
			default: 28,
		},
		round: {
			type: Number,
			default: 2,
		},
		//row横排，col为竖排
		direction: {
			type: [String],
			default: 'row',
		},

		//对齐方式：left,center,right
		align: {
			type: [String],
			default: 'left',
		},
		transprent: {
			type: [Boolean, String],
			default: true,
		},

		color: {
			type: String,
			default: 'primary',
		},
		//查询url
		url: {
			type: String,
			default() {
				return '';
			},
		},
		//查询功能编号
		funcCode: {
			type: String,
			default() {
				return '';
			},
		},
		//查询数据字典字段
		dictField: {
			type: String,
			default() {
				return '';
			},
		},
		timeout: Number,
		//是否加密
		cryptoEnabled: {
			type: Boolean,
			default: false
		},
		//是否脱敏
		desensitizeFlag: {
			type: Boolean,
			default: false
		},
		//是否防重复提交
		repeatEnabled: {
			type: Boolean,
			default: false
		},
		queryParams: {
			type: Object,
			default: () => { },
		},
		extend: {
			// 扩展属性，对象形式，存放组件的扩展属性
			type: Object,
			default: () => {
				return {};
			},
		},
	});
	const attrs = useAttrs();
	const emits = defineEmits(['update:modelValue', 'update:modelStr', 'change']);
	const allAttrs = computed(() => {
		return Object.assign(props.extend, attrs);
	});
	const _color = computed(() => {
		let color = props.color;
		if (props.followTheme && store.color) {
			color = store.color;
		}
		return color;
	});
	const nodeLabel = computed(() => {
		if (props.fieldNames.bindLabel) {
			return props.fieldNames.bindLabel;
		}
		return props.fieldNames.label;
	});
	const nodeValue = computed(() => {
		if (props.fieldNames.bindValue) {
			return props.fieldNames.bindValue;
		}
		return props.fieldNames.value;
	});
	const _value = ref(props.modelValue || []);
	const _strvalue = ref(props.modelStr);
	const myOptions = ref<any>(props.options || []);
	onMounted(() => {
		// getIndexBymodel(_data.value, props.selectedModel, 0, props.defaultValue)
		onSearch();
	});
	const onChange = (e : any) => {
		let list = [] as any;
		if (e && e.length > 0 && myOptions.value && myOptions.value.length > 0) {
			myOptions.value.forEach((item : any) => {
				e.forEach((valueItem : any) => {
					if (typeof item == 'string') {
						if (item === valueItem) {
							list.push(item);
						}
					} else {
						if (item[props.fieldNames.value] === valueItem) {
							list.push(item);
						}
					}
				});
			});
		}

		emits('change', list, e);
	};
	const onSearch = () => {
		let config : any = {};
		if (props.timeout && props.timeout > 0) {
			config.timeout = props.timeout;
		}
		let url = '';
		let params = Object.assign({}, props.queryParams);
		let headers = {} as any
		headers.cryptoEnabled = props.cryptoEnabled
		headers.repeatEnabled = props.repeatEnabled
		headers.desensitizeFlag = props.desensitizeFlag
		if (props.funcCode) {
			headers['func-code'] = props.funcCode;

			url = $api.common.send.url + props.funcCode;
		} else {
			if (props.url) {
				url = props.url;
			} else if (props.dictField) {
				headers['func-code'] = 'dict0011';
				url = $api.common.send.url + 'dict0011';
				params.dictField = props.dictField;
			} else {
				getStr();
				return;
			}
		}
		config.header = headers;
		http
			.post(url, params, config)
			.then((res : any) => {
				if (res.result === 'object') {
					myOptions.value = res.result.list || [];
				} else {
					myOptions.value = res.result;
				}
				getStr();
			})
			.catch(() => { });
	};
	function getStr() {
		if (!_value.value || _value.value.length <= 0) {
			_strvalue.value = [];
			return;
		}
		if (!myOptions.value || myOptions.value.length <= 0) {
			_strvalue.value = [];
			return;
		}
		let strList : any = [];
		myOptions.value.forEach((item : any) => {
			_value.value.forEach((valueItem : any) => {
				if (typeof item == 'string') {
					if (item === valueItem) {
						strList.push(item);
					}
				} else {
					if (item[props.fieldNames.value] === valueItem) {
						strList.push(item[props.fieldNames.label]);
					}
				}
			});
		});
		_strvalue.value = strList;
	}
	//------------------监听--------------------------------
	watch(
		() => [props.queryParams, props.dictField, props.funcCode, props.url],
		() => {
			onSearch();
		},
		{
			deep: true,
		}
	);
	watch(
		() => props.options,
		(val) => {
			myOptions.value = val || [];
			getStr();
		},
		{
			deep: true,
		}
	);
	watch(
		() => props.modelValue,
		(val) => {
			if (val) {
				_value.value = val;
			} else {
				_value.value = [];
			}
			getStr();
		},
		{
			deep: true,
		}
	);
	watch(
		() => _value,
		(val) => {
			getStr();
			emits('update:modelStr', _strvalue.value);
			emits('update:modelValue', val.value);

		},
		{
			deep: true,
		}
	);
</script>

<style></style>